Tag '/tags/release-4-7-3' created from /trunk:18412
[cyberduck.git] / Spotlight Importer / main.c
blobee8c2656a9b32757d06d7841083a8c88d4ccd9cb
1 /*
2 * Copyright (c) 2005 David Kocher. All rights reserved.
3 * http://cyberduck.ch/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * Bug fixes, suggestions and comments should be sent to:
16 * dkocher@cyberduck.ch
19 #include <CoreFoundation/CoreFoundation.h>
20 #include <CoreFoundation/CFPlugInCOM.h>
21 #include <CoreServices/CoreServices.h>
23 // -----------------------------------------------------------------------------
24 // constants
25 // -----------------------------------------------------------------------------
28 #define PLUGIN_ID "9187E6ED-3A06-4D80-9880-2DC715703869"
31 // Below is the generic glue code for all plug-ins.
33 // You should not have to modify this code aside from changing
34 // names if you decide to change the names defined in the Info.plist
38 // -----------------------------------------------------------------------------
39 // typedefs
40 // -----------------------------------------------------------------------------
42 // The import function to be implemented in GetMetadataForFile.c
43 Boolean GetMetadataForFile(void *thisInterface,
44 CFMutableDictionaryRef attributes,
45 CFStringRef contentTypeUTI,
46 CFStringRef pathToFile);
48 // The layout for an instance of MetaDataImporterPlugIn
49 typedef struct __MetadataImporterPluginType
51 MDImporterInterfaceStruct *conduitInterface;
52 CFUUIDRef factoryID;
53 UInt32 refCount;
54 } MetadataImporterPluginType;
56 // -----------------------------------------------------------------------------
57 // prototypes
58 // -----------------------------------------------------------------------------
59 // Forward declaration for the IUnknown implementation.
62 MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID);
63 void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance);
64 HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
65 void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
66 ULONG MetadataImporterPluginAddRef(void *thisInstance);
67 ULONG MetadataImporterPluginRelease(void *thisInstance);
68 // -----------------------------------------------------------------------------
69 // testInterfaceFtbl definition
70 // -----------------------------------------------------------------------------
71 // The TestInterface function table.
74 static MDImporterInterfaceStruct testInterfaceFtbl = {
75 NULL,
76 MetadataImporterQueryInterface,
77 MetadataImporterPluginAddRef,
78 MetadataImporterPluginRelease,
79 GetMetadataForFile
83 // -----------------------------------------------------------------------------
84 // AllocMetadataImporterPluginType
85 // -----------------------------------------------------------------------------
86 // Utility function that allocates a new instance.
87 // You can do some initial setup for the importer here if you wish
88 // like allocating globals etc...
90 MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID)
92 MetadataImporterPluginType *theNewInstance;
94 theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType));
95 memset(theNewInstance,0,sizeof(MetadataImporterPluginType));
97 /* Point to the function table */
98 theNewInstance->conduitInterface = &testInterfaceFtbl;
100 /* Retain and keep an open instance refcount for each factory. */
101 theNewInstance->factoryID = CFRetain(inFactoryID);
102 CFPlugInAddInstanceForFactory(inFactoryID);
104 /* This function returns the IUnknown interface so set the refCount to one. */
105 theNewInstance->refCount = 1;
106 return theNewInstance;
109 // -----------------------------------------------------------------------------
110 // DeallocCyberduck_Spotlight_ImporterMDImporterPluginType
111 // -----------------------------------------------------------------------------
112 // Utility function that deallocates the instance when
113 // the refCount goes to zero.
114 // In the current implementation importer interfaces are never deallocated
115 // but implement this as this might change in the future
117 void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance)
119 CFUUIDRef theFactoryID;
121 theFactoryID = thisInstance->factoryID;
122 free(thisInstance);
123 if (theFactoryID){
124 CFPlugInRemoveInstanceForFactory(theFactoryID);
125 CFRelease(theFactoryID);
129 // -----------------------------------------------------------------------------
130 // MetadataImporterQueryInterface
131 // -----------------------------------------------------------------------------
132 // Implementation of the IUnknown QueryInterface function.
134 HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
136 CFUUIDRef interfaceID;
138 interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
140 if (CFEqual(interfaceID,kMDImporterInterfaceID)){
141 /* If the Right interface was requested, bump the ref count,
142 * set the ppv parameter equal to the instance, and
143 * return good status.
145 ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance);
146 *ppv = thisInstance;
147 CFRelease(interfaceID);
148 return S_OK;
149 }else{
150 if (CFEqual(interfaceID,IUnknownUUID)){
151 /* If the IUnknown interface was requested, same as above. */
152 ((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance);
153 *ppv = thisInstance;
154 CFRelease(interfaceID);
155 return S_OK;
156 }else{
157 /* Requested interface unknown, bail with error. */
158 *ppv = NULL;
159 CFRelease(interfaceID);
160 return E_NOINTERFACE;
165 // -----------------------------------------------------------------------------
166 // MetadataImporterPluginAddRef
167 // -----------------------------------------------------------------------------
168 // Implementation of reference counting for this type. Whenever an interface
169 // is requested, bump the refCount for the instance. NOTE: returning the
170 // refcount is a convention but is not required so don't rely on it.
172 ULONG MetadataImporterPluginAddRef(void *thisInstance)
174 ((MetadataImporterPluginType *)thisInstance )->refCount += 1;
175 return ((MetadataImporterPluginType*) thisInstance)->refCount;
178 // -----------------------------------------------------------------------------
179 // SampleCMPluginRelease
180 // -----------------------------------------------------------------------------
181 // When an interface is released, decrement the refCount.
182 // If the refCount goes to zero, deallocate the instance.
184 ULONG MetadataImporterPluginRelease(void *thisInstance)
186 ((MetadataImporterPluginType*)thisInstance)->refCount -= 1;
187 if (((MetadataImporterPluginType*)thisInstance)->refCount == 0){
188 DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance );
189 return 0;
190 }else{
191 return ((MetadataImporterPluginType*) thisInstance )->refCount;
195 // -----------------------------------------------------------------------------
196 // Cyberduck_Spotlight_ImporterMDImporterPluginFactory
197 // -----------------------------------------------------------------------------
198 // Implementation of the factory function for this type.
200 void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
202 MetadataImporterPluginType *result;
203 CFUUIDRef uuid;
205 /* If correct type is being requested, allocate an
206 * instance of TestType and return the IUnknown interface.
208 if (CFEqual(typeID,kMDImporterTypeID)){
209 uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
210 result = AllocMetadataImporterPluginType(uuid);
211 CFRelease(uuid);
212 return result;
214 /* If the requested type is incorrect, return NULL. */
215 return NULL;